import { Component, Input, OnInit } from '@angular/core';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { NzMessageService } from 'ng-zorro-antd/message';
import { _HttpClient } from '@delon/theme';
import { ActivatedRoute } from '@angular/router';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { SysKeyValueService } from '@api/sys/service/sysKeyValue.service';
import { SysKeyValue } from '@api/sys/model/sysKeyValue.model';
import { SimpleListFieldAction } from '@api/simple/model/simpleListFieldAction';
import { snakeCase } from '@shared/utils/string';
import { SimpleListEditFormComponent } from '../form/form.component';
import { SimpleListField } from '@api/simple/model/simpleListField.model';
import { SimpleActionField } from '@api/simple/model/simpleActionField.model';
import { SimpleActionService } from '@api/simple/service/simpleAction.service';
import { SimpleListFormFields } from '@api/simple/model/simpleListFormFields.model';
import { SimpleActionFields } from '@api/simple/model/simpleActionFields.model';

@Component({
  selector: 'app-simple-list-edit-field',
  templateUrl: './field.component.html',
  styles: [
    `
      nz-select {
        width: 100%;
      }
    `,
  ],
})
export class SimpleListEditFieldComponent implements OnInit {
  _data: SimpleListFieldAction[] = [];

  @Input()
  listData: SimpleListFormFields = {};

  @Input()
  simpleListEditFormComponent!: SimpleListEditFormComponent;

  @Input()
  set data(value: SimpleListFieldAction[]) {
    let forms = this.form.controls.items as FormArray;
    value.forEach((item) => {
      forms.push(this.createForm());
      item.action?.fields.forEach((action) => {
        this.selectedActions.push(action.code!);
      });
    });
    this._data = value;
  }

  get data(): SimpleListFieldAction[] {
    return this._data;
  }

  public form: FormGroup = this.fb.group({
    items: this.fb.array([]),
  });

  fieldTypes: SysKeyValue[] = [];

  fixedTypes: SysKeyValue[] = [];

  formatTypes: SysKeyValue[] = [];

  constructor(
    private msgSrv: NzMessageService,
    public http: _HttpClient,
    protected route: ActivatedRoute,
    private fb: FormBuilder,
    private keyValueSerivice: SysKeyValueService,
    private simpleActionService: SimpleActionService,
  ) {}

  ngOnInit(): void {
    this.simpleActionService.findSimpleActionFieldsByCode('list_field_action_template').subscribe((res) => (this.actions = res.fields));
    this.keyValueSerivice.findByParentKeyPath('/SIMPLE/LIST_FIELD_TYPE').subscribe((res) => (this.fieldTypes = res));
    this.keyValueSerivice.findByParentKeyPath('/SIMPLE/FIXED_TYPE').subscribe((res) => (this.fixedTypes = res));
    this.keyValueSerivice.findByParentKeyPath('/SIMPLE/FORMAT_TYPE').subscribe((res) => (this.formatTypes = res));
  }

  createForm(): FormGroup {
    return this.fb.group({
      code: [null, [Validators.required]],
      name: [null, [Validators.required]],
      type: [null, [Validators.required]],
      value: [null],
      width: [null],
      acl: [null],
      i18n: [null],
      format: [null],
      pattern: [null],
      className: [null],
      sortFlag: [null],
      colSpan: [null],
      fixed: [null],
      action: [null],
    });
  }

  checked = false;
  loading = false;
  indeterminate = false;
  setOfCheckedId = new Set<string>();

  actions: SimpleActionField[] = [];

  selectedActions: string[] = [];

  updateCheckedSet(id: string, checked: boolean): void {
    if (checked) {
      this.setOfCheckedId.add(id);
    } else {
      this.setOfCheckedId.delete(id);
    }
  }

  refreshCheckedStatus(): void {
    const listOfEnabledData = this.data;
    this.checked = listOfEnabledData.every(({ id }) => this.setOfCheckedId.has(id!));
    this.indeterminate = listOfEnabledData.some(({ id }) => this.setOfCheckedId.has(id!)) && !this.checked;
  }

  onItemChecked(id: string, checked: boolean): void {
    this.updateCheckedSet(id, checked);
    this.refreshCheckedStatus();
  }

  onAllChecked(checked: boolean): void {
    this.data.forEach(({ id }) => this.updateCheckedSet(id!, checked));
    this.refreshCheckedStatus();
  }

  drop(event: CdkDragDrop<string[]>): void {
    moveItemInArray(this.data, event.previousIndex, event.currentIndex);
  }

  save() {
    this.form.markAsDirty();
    this.form.updateValueAndValidity();
  }

  addLine() {
    this.data.push({
      id: `${new Date().getTime()}`,
      type: 'string',
      fixed: '',
    });
    let forms = this.form.controls.items as FormArray;
    forms.push(this.createForm());
  }

  deleteLine() {
    if (this.setOfCheckedId.size == 0) {
      this.msgSrv.error('请选择行！');
      return;
    }
    let forms = this.form.controls.items as FormArray;
    this.setOfCheckedId.forEach((id) => {
      const index = this.data.findIndex((item) => {
        id == item.id;
      });
      this.data.splice(index, 1);
      forms.removeAt(index);
    });

    this.setOfCheckedId.clear();
  }

  validate() {
    let operate = this.data.find((item) => item.type == 'operate');
    if (operate) {
      const operateAction: SimpleActionFields = {
        id: operate.action?.id,
        code: `${this.listData.code}_list_field_action`,
        name: `${this.listData.name}列操作`,
        fields: [],
      };
      this.selectedActions.forEach((item) => {
        const action = this.actions.find((a) => item == a.code);
        operateAction.fields.push(action!);
      });
      operate.action = operateAction;
    }

    let forms = this.form.controls.items as FormArray;
    this.data.forEach((o, i) => {
      let form = forms.at(i) as FormGroup;
      Object.values(form.controls).forEach((control) => {
        if (control.invalid) {
          control.markAsDirty();
          control.updateValueAndValidity({ onlySelf: true });
        }
      });
    });
  }

  sortSwitch(value: Boolean, simpleListFieldAction: SimpleListFieldAction) {
    simpleListFieldAction.sortFlag = value ? 'Y' : 'N';
  }

  codeChange(simpleListFieldAction: SimpleListFieldAction) {
    simpleListFieldAction.column = snakeCase(simpleListFieldAction.code);
  }

  addFormFieldByListField() {
    const simpleListFields: SimpleListField[] = [];
    if (this.setOfCheckedId.size == 0) {
      this.msgSrv.error('请选择行！');
      return;
    }
    this.setOfCheckedId.forEach((id) => {
      const simpleListField = this.data.find((item) => item.id == id);
      simpleListFields.push(simpleListField as SimpleListField);
    });

    this.simpleListEditFormComponent.addLineByListField(simpleListFields);
  }

  typeChange(item: SimpleListField, index: any) {
    if (item.type == 'operate') {
      const i = this.data.findIndex((o) => o.type == 'operate' && item.code != o.code);
      if (i > -1) {
        item.type = '';
        this.msgSrv.error('已经存在了操作列！');
        return;
      }
      let forms = this.form.controls.items as FormArray;
      let form = forms.at(index);
    }
  }
}
